home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / bcfamily / source / viomode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-12  |  5.9 KB  |  248 lines

  1. //
  2. //      *******************************************************************
  3. //        JdeBP C++ Library Routines          General Public Licence v1.00
  4. //            Copyright (c) 1991,1992     Jonathan de Boyne Pollard
  5. //      *******************************************************************
  6. //
  7. // Part of FamAPI.LIB
  8. //
  9.  
  10. #include "famapi.h"
  11. #include "vio.h"
  12.  
  13. #define NO_CLEAR_FLAG 0x80
  14.  
  15. #pragma argsused
  16. //
  17. //    Get display mode
  18. //
  19. //    Known Bugs :     Little (& incorrect) processing of graphics modes.
  20. //
  21. USHORT _APICALL
  22. VioGetMode ( VIOMODEINFO far *PtrMode,
  23.              unsigned short VioHandle )
  24. {
  25.     volatile unsigned char far *BIOSrows = (volatile unsigned char far *)MK_FP(0x0040, 0x0084) ;
  26.     VIOMODEINFO minfo ;
  27.     unsigned short mode;
  28.  
  29.     mode = VioDosScreenMode() ;
  30.     minfo.col = mode >> 8 ;
  31.     mode &= 0x7F ;
  32.     if (*BIOSrows)
  33.         minfo.row = *(BIOSrows) + 1 ;
  34.     else
  35.         minfo.row = 25 ;            // Bodge for AMSTRAD PCs
  36.  
  37.     if (mode == 7) {
  38.         minfo.fbType = VGMT_MONOCHROME ;
  39.         minfo.color = 1 ;
  40.     } else if (mode == 0 || mode == 2) {
  41.         minfo.fbType = VGMT_OTHER | VGMT_DISABLEBURST ;
  42.         minfo.color = 4 ;
  43.     } else if (mode < 4) {
  44.         minfo.fbType = VGMT_OTHER ;
  45.         minfo.color = 4 ;
  46.     } else {
  47.         minfo.fbType = VGMT_OTHER | VGMT_GRAPHICS ;
  48.         minfo.color = 4 ;
  49.     }
  50.  
  51.     minfo.hres = minfo.vres = 0 ;
  52.  
  53.     if (PtrMode->cb > 2) {
  54.         PtrMode->fbType = minfo.fbType ;
  55.         if (PtrMode->cb > 3) {
  56.             PtrMode->color = minfo.color ;
  57.             if (PtrMode->cb > 4) {
  58.                 PtrMode->col = minfo.col ;
  59.                 if (PtrMode->cb > 6) {
  60.                     PtrMode->row = minfo.row ;
  61.                     if (PtrMode->cb > 8) {
  62.                         PtrMode->hres = minfo.hres ;
  63.                         if (PtrMode->cb > 10) {
  64.                             PtrMode->vres = minfo.vres ;
  65.                             if (PtrMode->cb > 12) {
  66.                                 PtrMode->fmt_ID = minfo.fmt_ID ;
  67.                                 if (PtrMode->cb > 13) {
  68.                                     PtrMode->attrib = minfo.attrib ;
  69.                                 }
  70.                             }
  71.                         }
  72.                     }
  73.                 }
  74.             }
  75.         }
  76.     }
  77.  
  78.     return NO_ERROR;
  79. }
  80.  
  81. #pragma argsused
  82. //
  83. //    Set display mode
  84. //
  85. //    Known Bugs :     Little (& incorrect) processing of graphics modes.
  86. //
  87. USHORT _APICALL
  88. VioSetMode ( const VIOMODEINFO far *pminfo,
  89.              unsigned short VioHandle )
  90. {
  91. //    UCHAR oldmode = VioDosScreenMode() & 0xFF ;
  92.     USHORT DCC, dipswitch, memsize ;
  93.     int HasEGAVGA = !VioDosGetEGASettings(&dipswitch, &memsize) ;
  94.     int HasVGA = !VioDosGetDCC(&DCC) ;
  95.  
  96.     volatile unsigned char far *BIOSmode =
  97.         (volatile unsigned char far *)MK_FP(0x0040, 0x0049) ;
  98.     volatile unsigned short far *BIOSflags =
  99.         (volatile unsigned short far *)MK_FP(0x0040, 0x0087) ;
  100.  
  101.     //
  102.     //    Don't support graphics or "non-compatible" modes
  103.     //
  104.     if (pminfo->fbType & (VGMT_GRAPHICS|0x80)) return ERROR_VIO_MODE ;
  105.  
  106.     //
  107.     //    The resolution requested determines which adapter we require.
  108.     //
  109.     //        720x400, 720x480 imply VGA (DOS doesen't support 480)
  110.     //        640x200, 320x200 imply EGA/CGA
  111.     //        720x350 implies MDA
  112.     //
  113.     if (pminfo->hres == 720) {
  114.         if (pminfo->vres == 350) {
  115.             //
  116.             //    MDA adapter requested.  We can only set 80x50 mono mode.
  117.             //
  118.             if (pminfo->fbType != VGMT_MONOCHROME ||
  119.                 pminfo->row != 25 || pminfo->col != 80 )
  120.                 return ERROR_VIO_MODE ;
  121.  
  122.             // Set the mode
  123.             _AL = 0x07 ;
  124.             _AH = 0x00 ;
  125.             geninterrupt(0x10) ;
  126.  
  127.         } else if (pminfo->vres == 400) {
  128.             //
  129.             //    VGA adapter requested.  First issue a mode change according
  130.             //    to whether the colour burst is enabled and the screen width,
  131.             //    the select the character size according to the screen depth.
  132.             //
  133.             if (!HasVGA) return ERROR_VIO_MODE ;
  134.             UCHAR newmode = NO_CLEAR_FLAG ;
  135.             if (pminfo->fbType == VGMT_MONOCHROME)
  136.                 newmode += 7 ;
  137.             else {
  138.                 if (pminfo->col == 80) {
  139.                     newmode += 2 ;
  140.                 } else if (pminfo->col != 40) {
  141.                     return ERROR_VIO_MODE ;
  142.                 }
  143.                 if (!(pminfo->fbType & VGMT_DISABLEBURST)) ++newmode ;
  144.             }
  145.  
  146.             if (pminfo->row != 50 && pminfo->row != 28 && pminfo->row != 25)
  147.                 return ERROR_VIO_MODE ;
  148.  
  149.             //    Enable default pallette loading
  150.             _AH = 0x12 ;
  151.             _BL = 0x31 ;
  152.             _AL = 0 ;
  153.             geninterrupt(0x10) ;
  154.  
  155.             //    Enable/Disable grey-scaling on next mode switch
  156.             _AL = (pminfo->fbType & VGMT_DISABLEBURST) ? 0 : 1 ;
  157.             _AH = 0x12 ;
  158.             _BL = 0x33 ;
  159.             geninterrupt(0x10) ;
  160.  
  161.             // Set the mode
  162.             _AL = newmode ;
  163.             _AH = 0x00 ;
  164.             geninterrupt(0x10) ;
  165.  
  166.             switch (pminfo->row) {
  167.                 case 50:
  168.                 _AX = 0x1112 ;                // Load & Display 8x8 characters
  169.                 _BX = 0 ;
  170.                 geninterrupt(0x10) ;
  171.                 break;
  172.             case 28:
  173.                 _AX = 0x1111 ;                // Load & Display 8x14 characters
  174.                 _BX = 0 ;
  175.                 geninterrupt(0x10) ;
  176.                 break;
  177.             case 25:
  178.                 _AX = 0x1114 ;                // Load & Display 8x16 characters
  179.                 _BX = 0 ;
  180.                 geninterrupt(0x10) ;
  181.                 break;
  182.             }
  183.  
  184.             // Select alternate print screen
  185.             _AX = 0x1200 ;
  186.             _BL = 0x20 ;
  187.             geninterrupt(0x10) ;
  188.  
  189.             *BIOSmode &= ~NO_CLEAR_FLAG ;
  190.             *BIOSflags &= ~NO_CLEAR_FLAG ;
  191.  
  192.         } else
  193.             return ERROR_VIO_MODE ;
  194.     } else if (pminfo->vres == 200) {
  195.         //
  196.         //    EGA/CGA adapter requested.  First issue a mode change according
  197.         //    to whether the colour burst is enabled and the screen width,
  198.         //    the select the character size according to the screen depth.
  199.         //
  200.         if (!HasEGAVGA) return ERROR_VIO_MODE ;
  201.         UCHAR newmode = NO_CLEAR_FLAG ;
  202.         if (pminfo->col == 80) {
  203.             newmode += 2 ;
  204.         } else if (pminfo->col != 40) {
  205.             return ERROR_VIO_MODE ;
  206.         }
  207.         if (!(pminfo->fbType & VGMT_DISABLEBURST)) ++newmode ;
  208.  
  209.         if (pminfo->row != 43 && pminfo->row != 25 )
  210.             return ERROR_VIO_MODE ;
  211.  
  212.         switch (pminfo->row) {
  213.             case 43:
  214.             *BIOSflags |= 1 ;
  215.             break;
  216.         case 25:
  217.             *BIOSflags &= ~1 ;
  218.             break;
  219.         }
  220.  
  221.         // Set the mode
  222.         _AL = newmode ;
  223.         _AH = 0x00 ;
  224.         geninterrupt(0x10) ;
  225.  
  226.         switch (pminfo->row) {
  227.             case 43:
  228.             _AX = 0x1112 ;                // Load & Display 8x8 characters
  229.             _BX = 0 ;
  230.             geninterrupt(0x10) ;
  231.             break;
  232.         case 25:
  233.             _AX = 0x1111 ;                // Load & Display 8x14 characters
  234.             _BX = 0 ;
  235.             geninterrupt(0x10) ;
  236.             break;
  237.         }
  238.  
  239.         *BIOSmode &= ~NO_CLEAR_FLAG ;
  240.         *BIOSflags &= ~NO_CLEAR_FLAG ;
  241.  
  242.     } else
  243.         return ERROR_VIO_MODE ;
  244.  
  245.     return NO_ERROR ;
  246. }
  247.  
  248.